﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.IO;

namespace Lm.Common.Csv
{
    /// <summary>
    /// 此类读取CVS文件时，位置指针一直向前移动；
    /// GetDataTable()和Read()使用相同的位置指针；
    /// 例如，如果已经使用Read()读取了3行，那么再GetDataTable()时，只能读取第4行及以后的记录；
    /// 调用GetDataTable()将导致位置指针移动到最后；
    /// 调用Reset()将把位置指针重置到开头；
    /// </summary>
    public class CSVReader : Lm.Common.Csv.ICSVReader
    {
        protected string ItemSeparator { get; set; }
        protected string CsvFile { get; set; }
        protected Encoding CsvFileEncoding { get; set; }

        protected StreamReader FileReader { get; set; }
        protected List<string> Columns { get; set; }
        //protected string CurrentLine { get; set; }
        protected string[] DataList { get; set; }

        public CSVReader(string itemSeparator, string csvFile, Encoding csvFileEncoding)
        {
            this.ItemSeparator = itemSeparator;
            this.CsvFile = csvFile;
            this.CsvFileEncoding = csvFileEncoding;
        }

        public bool Read()
        {
            if (this.FileReader == null)
            {
                this.FileReader = new StreamReader(this.CsvFile, this.CsvFileEncoding);
            }

            if (this.Columns == null)
            {
                var titleLine = this.FileReader.ReadLine();
                if (titleLine == null)
                { return false; }
                this.Columns = titleLine.Split(new string[] { this.ItemSeparator }, StringSplitOptions.None).ToList();
            }

            var dataLine = this.FileReader.ReadLine();
            if (dataLine == null)
            {
                this.DataList = null;
                return false;
            }
            else
            {
                this.DataList = dataLine.Split(new string[] { this.ItemSeparator }, StringSplitOptions.None);
                return true;
            }
        }

        public string this[string ColumnName]
        {
            get
            {
                if (this.DataList == null)
                { return null; }
                
                if (DataList.Length != this.Columns.Count)
                { return null; }
                var index = this.Columns.IndexOf(ColumnName);
                if (index < 0)
                { return null; }
                return DataList[index];
            }
        }

        public DataTable GetDataTable()
        {
            DataTable dt = null;
            while (this.Read())
            {
                if (dt == null)
                { dt = new DataTable(); }
                if (dt.Columns.Count == 0)
                {
                    foreach (var c in this.Columns)
                    {
                        dt.Columns.Add(c, typeof(string));
                    }
                }

                var row = dt.NewRow();
                foreach (DataColumn c in dt.Columns)
                {
                    row[c.ColumnName] = this[c.ColumnName];
                }
                dt.Rows.Add(row);
            }
            return dt;
        }

        public void Dispose()
        {
            this.FileReader.Dispose();
        }


        public void Reset()
        {
            if (this.FileReader != null)
            {
                try
                {
                    this.FileReader.Dispose();
                }
                catch 
                { }
                this.FileReader = null;
            }
            this.Columns = null;
            this.DataList = null;
        }
    }
}
